parser grammar CParser;

options {
  language = Java;
  tokenVocab = CLexer;
  output = AST;
  ASTLabelType = MiArbol;
  
}

tokens {
    LISTA_INST;
}

@header {
package PL.prac10;
}

@rulecatch {catch (RecognitionException e) {
  throw e;}
 }

entrada: (definicion|cabecera)* EOF -> ^(LISTA_INST (definicion)* (cabecera)*);   

definicion: TIPO^ IDENT (COMA! IDENT)* SEPARADOR!;
cabecera: (VOID|TIPO)(IDENT^|MAIN^) APARENTESIS! (VOID | parametros)? CPARENTESIS! ALLAVE! cuerpo* CLLAVE!;
  parametros: llamada_variable (COMA! llamada_variable)*;
  llamada_variable: TIPO (ASTERISCO)? IDENT (ACORCHETE CCORCHETE)?;
  
  cuerpo: (asignacion|definicion|sentencia_break|llamada_funcion|bucle|condicion);
    llamada_funcion: IDENT^ APARENTESIS! ((tipos) (COMA! (tipos)*)?)? CPARENTESIS! SEPARADOR!;
        tipos: (IDENT^ (ACORCHETE! (NUMERO) CCORCHETE!)?) |NUMERO| CADENA|CARACTER;
    sentencia_break: BREAK^ SEPARADOR!;
      bucle: WHILE^ comparacion sentencia;
      condicion: IF^ comparacion sentencia ({(input.LA(1) == ELSE)}? (senelse) | );//Miro el siguiente token, si es else puedes meterte por ahí.
      senelse: ELSE^ sentencia_break;
        sentencia: (ALLAVE! cuerpo+ CLLAVE! |cuerpo);
        comparacion:APARENTESIS! reglas ((AND | OR) reglas)* CPARENTESIS!;
          reglas:( operacion (COMPARADORES^ operacion)?|cond_aritmetico);
            cond_aritmetico: IDENT COMPARADORES NUMERO INTERROGANTE NUMERO DOSPUNTOS NUMERO;
      asignacion: IDENT IGUAL^ operacion SEPARADOR!;
        operacion: exp_mult ((MAS^|MENOS^) exp_mult)*;
          exp_mult: exp_base ((ASTERISCO^|BARRA^)exp_base)*;
            exp_base: NUMERO | IDENT | (APARENTESIS! operacion CPARENTESIS!);